{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. 写一个可以将MNIST图片向任意方向（上，下，左，右）移动一个像素功能。然后对训练集中的每张图片，创建四个位移后的副本，每个方向一个，添加到训练集。最后，在这个扩展过的训练集上训练模型，衡量其在测试集上的精度，来优化精度，这种人工扩展训练集的技术成为数据增广或训练集扩展"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "c:\\users\\baohuhe\\appdata\\local\\programs\\python\\python37\\lib\\site-packages\\sklearn\\feature_extraction\\text.py:17: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated since Python 3.3,and in 3.9 it will stop working\n",
      "  from collections import Mapping, defaultdict\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.datasets import fetch_mldata\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.metrics import confusion_matrix\n",
    "from sklearn.model_selection import cross_val_score\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.metrics import precision_score, recall_score\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from scipy.ndimage.interpolation import shift\n",
    "from sklearn.model_selection import cross_val_predict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_img1(X,i):\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image, cmap=matplotlib.cm.binary)\n",
    "    plt.show()\n",
    "    \n",
    "def show_img2(X,i):\n",
    "    some_digit = X[i]\n",
    "    some_digit_image = some_digit.reshape(28,28)\n",
    "    plt.imshow(some_digit_image, cmap=matplotlib.cm.binary, interpolation='nearest')\n",
    "    plt.axis('off')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shift_img(img, dy, dx):\n",
    "    img = img.reshape(28, 28)\n",
    "    shifted_image = shift(img, [dy, dx])\n",
    "    return shifted_image.reshape(-1)\n",
    "    \n",
    "def show_shifted_img(X,i,dy,dx):\n",
    "    some_digit = X[i]\n",
    "    some_digit_shifted = shift_img(some_digit, dy, dx).reshape(28,28)\n",
    "    plt.imshow(some_digit_shifted, cmap=matplotlib.cm.binary, interpolation='nearest')\n",
    "    plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "mnist = fetch_mldata('MNIST original', data_home='./')\n",
    "X,y = mnist['data'], mnist['target']\n",
    "X_train, X_test, y_train, y_test = X[:60000], X[60000:], y[0:60000], y[60000:]\n",
    "shuffle_index = np.random.permutation(60000)\n",
    "X_train, y_train = X_train[shuffle_index], y_train[shuffle_index]\n",
    "y_train_9 = (y_train==9)\n",
    "y_test_9 = (y_test==9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9., 7., 9., 9., 4., 9., 4., 8., 7., 4.])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_img2(X_train,0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr = np.array([0,0,0,0,0,\n",
    "                     0,0,1,0,0,\n",
    "                     0,1,0,1,0,\n",
    "                     0,0,1,0,0,\n",
    "                     0,0,0,0,0]).reshape(5,5)\n",
    "test_arr"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0]])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_down = shift(test_arr, [1,0])\n",
    "test_arr_down"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 0],\n",
       "       [0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_up = shift(test_arr, [-1,0])\n",
    "test_arr_up"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 0, 0, 1, 0],\n",
       "       [0, 0, 1, 0, 1],\n",
       "       [0, 0, 0, 1, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_right = shift(test_arr, [0,1])\n",
    "test_arr_right"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[0, 0, 0, 0, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [1, 0, 1, 0, 0],\n",
       "       [0, 1, 0, 0, 0],\n",
       "       [0, 0, 0, 0, 0]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_arr_left = shift(test_arr, [0,-1])\n",
    "test_arr_left"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 784)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_digit = X_train[0:1]\n",
    "test_digit.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 使用一个简单的图形矩阵演示shift方法时如何操作的，观察矩阵和图像的变化关系"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x216 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,3))\n",
    "plt.subplot(1,5,1)\n",
    "plt.title('Original', fontsize=14)\n",
    "plt.imshow(test_arr, cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,2)\n",
    "plt.title('move 1pixel to right', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [0,1]), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,3)\n",
    "plt.title('move 1pixel to below', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [1,0]), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,4)\n",
    "plt.title('move 1pixel to left', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [0,-1]), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,5)\n",
    "plt.title('move 1pixel to above', fontsize=14)\n",
    "plt.imshow(shift(test_arr, [-1,0]), cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 把刚才的shift方法使用在真正的mnist数据上，确认效果正常"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1080x216 with 5 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(15,3))\n",
    "plt.subplot(1,5,1)\n",
    "plt.title('Original', fontsize=14)\n",
    "plt.imshow(test_digit.reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,2)\n",
    "plt.title('move 5pixel to right', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,0,5).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,3)\n",
    "plt.title('move 5pixel to below', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,5,0).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,4)\n",
    "plt.title('move 5pixel to left', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,0,-5).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.subplot(1,5,5)\n",
    "plt.title('move 5pixel to above', fontsize=14)\n",
    "plt.imshow(shift_img(test_digit,-5,0).reshape(28,28), cmap=matplotlib.cm.binary)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train_shifted = []\n",
    "y_train_shifted = []\n",
    "\n",
    "for img, label in zip(X_train, y_train):\n",
    "    for dx, dy in [[1,0],[0,1], [-1,0],[0,-1]]:\n",
    "        X_train_shifted.append(shift_img(img, dx, dy))\n",
    "        y_train_shifted.append(label)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000, 784)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train_shifted = np.array(X_train_shifted)\n",
    "X_train_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(240000,)"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted = np.array(y_train_shifted)\n",
    "y_train_shifted.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9., 9., 9., ..., 4., 4., 4.])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted[0:10]\n",
    "y_train_shifted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_shifted_9 = (y_train_shifted==9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',\n",
       "           metric_params=None, n_jobs=1, n_neighbors=5, p=2,\n",
       "           weights='uniform')"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf = KNeighborsClassifier()\n",
    "knn_clf.fit(X_train_shifted, y_train_shifted_9)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([9., 9., 9., 9., 7., 7., 7., 7., 9., 9.])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train_shifted[0:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 784)"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_img1 = X_train_shifted[0:1]\n",
    "test_img1.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ True])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn_clf.predict(test_img1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_score = cross_val_score(knn_clf, X_train_shifted, y_train_shifted_9, cv=5, scoring='accuracy')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "train_score.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_pred = cross_val_predict(knn_clf, X_train_shifted, y_train_shifted_9, cv=5, verbose=3, n_jobs=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_train_pred[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_train_shifted_9, y_train_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('精度：{0:.2f} %'.format(100*precision_score(y_train_shifted_9, y_train_pred)))\n",
    "print('召回率：{0:.2f} %'.format(100*recall_score(y_train_shifted_9, y_train_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_test_pred = knn_clf.predict(X_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "confusion_matrix(y_test_9, y_test_pred)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('精度：{0:.2f} %'.format(100*precision_score(y_test_9, y_test_pred)))\n",
    "print('召回率：{0:.2f} %'.format(100*recall_score(y_test_9, y_test_pred)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "accuracy_score(y_test_9, y_test_pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*   由于代码运行消耗太长时间，跑了一下午+一晚上，早上一看电脑已关机，最终结果没有出来，请老师酌情给分，谢谢老师"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
